/**
 * 
 */
package info.niwota.webime.http;

import java.net.BindException;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

/**
 * @author qiangli
 * 
 */
public class HttpConnector implements Connector, Lifecycle, Runnable {
	private static final String PROTOCOL = "http";

	private static final String TAG = "HttpConnector";

	private static final int ANY_PORT = 0;

	private int instanceId = 0;


	private final String host = "localhost";

	private int port = ANY_PORT;

	private PI pi;

	private ServerSocket ss;

	private Thread th;

	private ServerContext ctx;

	/** 
	 */
	public HttpConnector() {
	}

	public void setPI(PI pi) {
		this.pi = pi;
	}

	public int getPort() {
		return port;
	}

	public String getHost() {
		return host;
	}

	public void run() {
	
		URI base = null;
		try {
			base = new URL("http", host, port, "/").toURI();
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (URISyntaxException e1) {
			e1.printStackTrace();
		}
		
		while (ss != null) {
			try {
				if (Debug.DEBUG) {
					Log.d(TAG, "HTTP Connector [" + host + ":" + port + " "
							+ (++instanceId) + "]");
				}
				
				Socket s = ss.accept();
				if (pi != null) {
					WebContext wc = new WebContext(PROTOCOL);
					wc.serverContext = ctx;
					wc.baseUri = base;

					pi.service(wc, s);
				} else {
					if (Debug.DEBUG) {
						Log.d(TAG, "No PI set.");
					}
				}
			} catch (Exception e) {
				// e.printStackTrace();
			}
		}
	}

	public void shutdown() {
		if (Debug.DEBUG) {
			Log.d(TAG, "HTTP Connector stopping...");
		}
		
		try {
			ss.close();
			ss = null;
			ctx = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
		//
		th.interrupt();
		
		if (Debug.DEBUG) {
			Log.d(TAG, "HTTP Connector stopped");
		}
		
	}

	public void startup() {
		if (Debug.DEBUG) {
			Log.d(TAG, "HTTP Connector starting...");
		}
		try {
			ss = new ServerSocket(port);
			if (port == ANY_PORT) {
				port = ss.getLocalPort();
			}
		} catch (BindException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		//
		th = new Thread(this);
		th.setDaemon(true);
		th.start();
		//
		if (Debug.DEBUG) {
			Log.d(TAG, "HTTP Connector started");
		}
	}

	public void init(ServerContext ctx) {
		this.ctx = ctx;
		
		port = ctx.port;
	}
}
